﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using FarseerPhysics.Dynamics;

//This represents one line object

namespace Doodleberg
{
    class Line
    {
        private Vector2 v1;
        private Vector2 v2;

        public Body body;

        private float angle;
        private float length;

        public float restitution;
        
        public bool deletable;

        public Line(float res)
        {
            v1 = Vector2.Zero;
            v2 = Vector2.Zero;
            angle = 0.0f;
            length = 0.0f;
            restitution = res;
            calc();
        }

        public Line(Vector2 vin1, Vector2 vin2, float res)
        {
            v1 = vin1;
            v2 = vin2;
            restitution = res;
            calc();
        }

        public void setVert(int index, Vector2 vin)
        {
            if (index == 1)
                v1 = vin;
            else
                v2 = vin;
            calc();
        }

        public void setVert(int index, float vinx, float viny)
        {
            if (index == 1)
                v1 = new Vector2(vinx, viny);
            else
                v2 = new Vector2(vinx, viny);
            calc();
        }

        public float getAngle()
        {
            return angle;
        }

        public float getLength()
        {
            return length;
        }

        public Vector2 getVert(int index)
        {
            if (index == 1)
                return v1;
            else
                return v2;
        }

        public Vector2 getDirectionalVector()
        {
            return Vector2.Normalize(Vector2.Subtract(v2, v1));
        }

        public Vector2 getNormalVector()
        {
            return Vector2.Normalize(new Vector2(-getDirectionalVector().Y, getDirectionalVector().X));
        }

        //Returns the distance to the line segment from a point
        public float getDistanceTo(float ptx, float pty)
        {
            //Angles to line from v1 to pt, line itself, and line to line from v1 to pt
            double beta = Math.Atan((pty - v1.Y) / (ptx - v1.X));
            double theta = Math.Abs(beta - angle);

            double precalc = Math.Sqrt(Math.Pow(v1.Y - pty, 2) + Math.Pow(v1.X - ptx, 2));
            float dist = (float)(precalc * Math.Sin(theta));

            float lpos = (float)(precalc * Math.Cos(theta));

            //Adjust distance if point is off line ends
            //(dist would be measured to nonexistent extension of the line)

            if (ptx < v1.X)
            {
                dist = (float)precalc;
            }
            else if (ptx > v2.X)
            {
                dist = (float)Math.Sqrt(Math.Pow(v2.Y - pty, 2) + Math.Pow(v2.X - ptx, 2));
            }

            return Math.Abs(dist);
        }

        private void calc()
        {
            angle = (float)Math.Atan2(v2.Y - v1.Y, v2.X - v1.X);
            length = Vector2.Distance(v1, v2);
        }


        public void draw(SpriteBatch spriteBatch)
        {
            Texture2D usetex;
            if (!deletable)
                usetex = Global.level.tex_linehard;
            else
                usetex = Global.level.tex_linedrawn;

            Vector2 temp;
            if (getVert(1).X < getVert(2).X)
                temp = getVert(1);
            else
                temp = getVert(2);

            spriteBatch.Draw(
                usetex,
                temp,
                null,
                Color.White,
                getAngle(),
                new Vector2(0.0f, usetex.Height / 2),
                new Vector2(getLength() / 100.0f, 1.0f),
                SpriteEffects.None,
                0.7f);
        }
    }
}
